﻿using NCS.IConnect.Cloud.Core.Properties;
using NCS.IConnect.Core;
using NCS.IConnect.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;

namespace NCS.IConnect.Cloud.Core
{
    /// <summary>
    ///iConnect specific Guard for general validation.
    /// </summary>
    public static class Guard2
    {
        private static readonly CultureInfo[] allCultures = CultureInfo.GetCultures(CultureTypes.AllCultures);

        /// <summary>
        /// Ensure the give configurationsection exists, otherwize throw a <see cref="ConfigurationErrorsException"/> if miss the configuration section.
        /// </summary>
        /// <param name="configSectionName">Name of the configuration section.</param>
        public static void EnsureConfigSectionExists(string configSectionName)
        {
            Guard.ArgumentNotNullOrEmpty(configSectionName, "configSectionName");
            // TODO: to validate configuration source
            if (null == ConfigurationManager.GetSection(configSectionName))
            {
                throw new ConfigurationErrorsException(ResourceUtility.Format(Resources.ExceptionMissingConfigSection, configSectionName));
            }
        }

        /// <summary>
        /// Ensures the valid database name.
        /// </summary>
        /// <param name="databaseName">Name of the database.</param>
        public static void EnsureValidDatabaseName(string databaseName)
        {
            Guard.ArgumentNotNullOrEmpty(databaseName, "databaseName");
            foreach (ConnectionStringSettings connectionSetting in ConfigManager.GetConfigurationSection<ConnectionStringsSection>("connectionStrings").ConnectionStrings)
            {
                if (connectionSetting.Name == databaseName)
                {
                    return;
                }
            }
            throw new ConfigurationErrorsException(ResourceUtility.Format(Resources.ExceptionMissingConfigSection, databaseName));
        }

        /// <summary>
        /// Ensures the name of the valid culture.
        /// </summary>
        /// <param name="cultureName">Name of the culture.</param>
        public static void EnsureValidCultureName(string cultureName)
        {
            Guard.ArgumentNotNull(cultureName, "cultureName");
            if (!allCultures.Any(ci => ci.Name == cultureName))
            {
                throw new CultureNotFoundException(ResourceUtility.Format(Resources.ExceptionInvalidCultureName, cultureName));
            }
        }

        /// <summary>
        /// Ensures the sequence not null or empty.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sequence">The sequence.</param>
        /// <param name="sequenceArgurementName">Name of the sequence argurement.</param>
        public static void EnsureSequenceNotNullOrEmpty<T>(IEnumerable<T> sequence, string sequenceArgurementName)
        {
            Guard.ArgumentNotNull(sequence, "sequence");
            if (!sequence.Any())
            {
                throw new ArgumentException(ResourceUtility.Format(Resources.ExceptionSequenceNoElement), sequenceArgurementName);
            }
        }
    }
}
